package com.dgut.fastdfs.controller;


import cn.hutool.core.io.FileUtil;
import com.dgut.fastdfs.commom.UpLoadConstant;
import com.dgut.fastdfs.entity.MultipartFileParam;
import com.dgut.fastdfs.utils.ChunkUploadUtil;
import com.dgut.fastdfs.utils.FastDFSClientUtil;
import com.dgut.fastdfs.utils.RedisUtil;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.exception.FdfsIOException;
import com.github.tobato.fastdfs.service.AppendFileStorageClient;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;


/**
 * @author ：陈文浩
 * @date ：Created in 2020/2/18 20:36
 * @description：
 */
@RestController
public class FileController {

    //视频缓存时间,秒:1天
    private final Integer cacheTime = 60 * 60 * 24;
    @Autowired
    AppendFileStorageClient appendFileStorageClient;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    FastDFSClientUtil fastDFSClientUtil;
    private Logger logger = Logger.getLogger(FileController.class);
    @Autowired
    private ChunkUploadUtil chunkUploadUtil;

    @RequestMapping("/")
    public String index() {

        return "index";
    }

    @PostMapping("/uploadTest")
    public String uploadTest(@RequestParam("file") MultipartFile file) {
        System.out.println(file.getOriginalFilename());
        return "OK,filename=" + file.getOriginalFilename();
    }


    @PostMapping("/upload")
    public String fdfsUpload(@RequestParam("file") MultipartFile file) {
        String fileUrl = "fail";
        try {
            fileUrl = fastDFSClientUtil.uploadFile(file);

        } catch (IOException e) {
            e.printStackTrace();
            return fileUrl;
        }
        return fileUrl;
    }

    @PostMapping(value = "/chunkUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map chunkUpload(MultipartFileParam file) {
        System.out.println("***传输任务开始***");
        System.out.println("fileName=" + file.getTaskId());
        String fileUrl = "fail";
        String path = "C:\\Users\\Administrator\\Desktop\\memory\\upload";
        Map<String, String> map = new HashMap<>();
        map.put("path", fileUrl);
        try {
            fileUrl = chunkUploadUtil.chunkUploadByMappedByteBuffer(file, path);
            map.put("path", fileUrl);
        } catch (Exception e) {
            e.printStackTrace();
            return map;
        }
        System.out.println("path=" + map.get("path"));
        System.out.println("***传输任务结束***");
        return map;
    }

    @PostMapping(value = "/fastDfsChunkUpload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map chunkUpload1(MultipartFileParam multipartFileParam, HttpServletResponse response) {
        Map<String, String> map = new HashMap<>();
        long chunk = multipartFileParam.getChunkNumber();
        long totalChunk = multipartFileParam.getTotalChunks();
        long chunkSize = multipartFileParam.getChunkSize();
        long historyUpload = (chunk - 1) * chunkSize;
        String md5 = multipartFileParam.getIdentifier();
        MultipartFile file = multipartFileParam.getFile();
        String fileName = FileUtil.extName(file.getOriginalFilename());
        StorePath path = null;
        String groundPath;

        try {
            if (chunk == 1) {
                path = appendFileStorageClient.uploadAppenderFile(UpLoadConstant.DEFAULT_GROUP, file.getInputStream(),
                        file.getSize(), fileName);
                if (path == null) {
                    map.put("result", "上传第一个就错了");
                    response.setStatus(500);
                    return map;
                } else {
                    redisUtil.setObject(UpLoadConstant.uploadChunkNum + md5, 1, cacheTime);
                    map.put("result", "上传成功");
                }
                groundPath = path.getPath();
                redisUtil.setObject(UpLoadConstant.fastDfsPath + md5, groundPath, cacheTime);

            } else {
                groundPath = (String) redisUtil.getObject(UpLoadConstant.fastDfsPath + md5);
                appendFileStorageClient.modifyFile(UpLoadConstant.DEFAULT_GROUP, groundPath, file.getInputStream(),
                        file.getSize(), historyUpload);
                Integer chunkNum = (Integer) redisUtil.getObject(UpLoadConstant.uploadChunkNum + md5);
                chunkNum = chunkNum + 1;
                redisUtil.setObject(UpLoadConstant.uploadChunkNum + md5, chunkNum, cacheTime);
            }
            Integer num = (Integer) redisUtil.getObject(UpLoadConstant.uploadChunkNum + md5);
            if (totalChunk == num) {
                response.setStatus(200);
                map.put("result", "上传成功");
                map.put("path", groundPath);
                redisUtil.del(UpLoadConstant.uploadChunkNum + md5);
                redisUtil.del(UpLoadConstant.fastDfsPath + md5);
            }
        } catch (FdfsIOException | SocketTimeoutException e) {
            response.setStatus(407);
            map.put("result", "重新发送");
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            redisUtil.del(UpLoadConstant.uploadChunkNum + md5);
            redisUtil.del(UpLoadConstant.fastDfsPath + md5);
            response.setStatus(500);
            map.put("result", "upload error");
            return map;
        }
        System.out.println("result=" + map.get("result"));
        System.out.println("path=" + map.get("path"));
        return map;
    }
}
